<!DOCTYPE HTML>
<html>
<head>
<title>Boomerang Howto #3: Measure a user's bandwidth/latency along with page load time</title>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css" href="../boomerang-docs.css">
</head>
<body>
<span style="float:right;"><a href="../">All Docs</a> | <a href="index.html">Index</a></span>
<h1>Boomerang Howto #3:<br>Measure a user's bandwidth/latency along with page load time</h1>
<p>
See <a href="../use-cases.html#uc-3">use cases #3</a> &amp; <a href="../use-cases.html#uc-5">#5</a> for a description of this requirement.
</p>

<p>
By default, boomerang always measures the user's bandwidth and HTTP latency and adds these numbers to the beacon
that it sends back.  In reality, the bandwidth plugin (<code>BOOMR.plugins.BW</code>) does this, but since that's
bundled along with boomerang, the difference is purely academic.  There are a few things you need to know in order
to use the bandwidth detection code effectively.
</p>

<p>
First, bandwidth detection through javascsript is not accurate.  If the user's network is lossy or is shared with
other users, or network traffic is bursty, real bandwidth can vary over time.  The measurement we take is based
over a short period of time, and this may not be representative of the best or worst cases.  We try to cover for
that by measuring not just the bandwidth, but also the error value in that measurement.
</p>

<p>
Simply adding boomerang to a page and calling the <code>init()</code> method is sufficient to start the bandwidth
test and beacon its results back to the server.  This is the code you'd use:
</p>
<pre>
&lt;script src="boomerang.js" type="text/javascript"&gt;&lt;/script&gt;
&lt;script type="text/javascript"&gt;
BOOMR.init({
	beacon_url: "http://yoursite.com/path/to/beacon.php",
	BW: {
		base_url: "http://base_url/to/bandwidth/images/"
	}
});
&lt;/script&gt;
</pre>
<p>
The default value of the <code>BW.base_url</code> parameter is <code>images/</code>, so if your bandwidth detection
images are placed in a subdirectory of the current directory called <code>images</code>, then you do not need
to set the <code>BW.base_url</code> parameter.  It is a good practice though, as you might have pages in multiple
directories.
</p>

<p>
Now while this is the minimum code required to measure bandwidth and latency and have it beaconed back, it isn't
the best option for your user.  The test will run every time the user visits a page on your site even though
their bandwidth probably hasn't changed (apart from regular fluctuations).  It's far better to store the bandwidth
in a cookie for a fixed period of time, and read it out of the cookie if it exists.  Now it is possible that the
user moves between several networks, eg: a laptop used at home, at work and at a coffee shop.  The bandwidth and
latency at these locations may be different, and it's necessary to measure them separately.  We detect a change
in network through the user's IP address, so in order to store the user's bandwidth in a cookie, you will need
to tell boomerang what the user's IP address is.  You do this through the <code>user_id</code> parameter.
</p>

<pre>
&lt;script src="boomerang.js" type="text/javascript"&gt;&lt;/script&gt;
&lt;script type="text/javascript"&gt;
BOOMR.init({
	beacon_url: "http://yoursite.com/path/to/beacon.php",
	user_ip: "&lt;user's ip&gt;",
	BW: {
		base_url: "http://base_url/to/bandwidth/images/"
	}
});
&lt;/script&gt;
</pre>

<p>
As far as I know, there's no way in javascript to figure out the user's IP address.  You'll have to do this server
side and write the value into your code.
</p>

<h2>IPv4 optimisations</h2>
<p>
If your user has an IPv4 address, then we also strip out the last part of the IP and use that rather than the entire
IP address.  This helps if users use DHCP on the same ISP where their IP address changes frequently, but they stay
within the same subnet.  If the user has an IPv6 address, we use the entire address.
</p>

<h2>The Cookie</h2>
<p>
You may want to customise the name of the cookie where the bandwidth will be stored.  By default this is
set to <code>BA</code>, but you can change it using the <code>BW.cookie</code> parameter.
</p>

<pre>
&lt;script src="boomerang.js" type="text/javascript"&gt;&lt;/script&gt;
&lt;script type="text/javascript"&gt;
BOOMR.init({
	beacon_url: "http://yoursite.com/path/to/beacon.php",
	user_ip: "&lt;user's ip&gt;",
	BW: {
		base_url: "http://base_url/to/bandwidth/images/",
		cookie: "BW"
	}
});
&lt;/script&gt;
</pre>

<p>
This cookie is set to expire in 7 days.  You can change its lifetime using the <code>BW.cookie_exp</code> parameter.
The value is in seconds.  During that time, you can also read the value of the cookie on the server side.  Its
format is as follows:
</p>

<pre>
BA=ba=<span class="ni">nnnnnnn</span>&amp;be=<span class="ni">nnn.nn</span>&amp;l=<span class="ni">nnnn</span>&amp;le=<span class="ni">nn.nn</span>&amp;ip=<span class="ni">iiiiii</span>&amp;t=<span class="ni">sssssss</span>;
</pre>
<p>
The parameters are defined as:
</p>
<dl>
<dt>ba</dt>
<dd>[integer] [bytes/s] The user's bandwidth to your server</dd>
<dt>be</dt>
<dd>[float] [bytes/s] The 95% confidence interval margin of error in measuring the user's bandwidth</dd>
<dt>l</dt>
<dd>[float] [ms] The HTTP latency between the user's computer and your server</dd>
<dt>le</dt>
<dd>[float] [ms] The 95% confidence interval margin of error in measuring the user's latency</dd>
<dt>ip</dt>
<dd>[ip address] The user's IPv4 or IPv6 address that was passed as the <code>user_ip</code> parameter to the <code>init()</code> method</dd>
<dt>t</dt>
<dd>[timestamp] The browser time (in seconds since the epoch) when the cookie was set</dd>
</dl>

<p>
These parameters are also sent in the beacon (See <a href="howto-0.html">HOWTO #0</a>), but having them in the
cookie means that you can customise your users experience based on the bandwidth before you serve a request.
</p>

<h2>Disabling the bandwidth check</h2>
<p>
Finally, there may be cases when you want to completely disable the bandwidth test.  Perhaps you know that
your user is on a slow network, or pays by the byte (the bandwidth test uses a lot of bandwidth), or is on
a mobile device that cannot handle the load.  In such cases you have two options.
</p>
<ol>
<li>Delete the bandwdith plugin from your copy of boomerang.js</li>
<li>Set the <code>BW.enabled</code> parameter to <code>false</code>:</li>
</ol>
<pre>
&lt;script src="boomerang.js" type="text/javascript"&gt;&lt;/script&gt;
&lt;script type="text/javascript"&gt;
BOOMR.init({
	BW: { enabled: false  }
});
&lt;/script&gt;
</pre>

<p>
The latest code and docs is available on <a href="http://github.com/yahoo/boomerang/">github.com/yahoo/boomerang</a>
</p>

<p id="results">
</p>

<script src="../../boomerang.js" type="text/javascript"></script>
<script src="howtos.js" type="text/javascript"></script>
<script type="text/javascript">
BOOMR.init({
		user_ip: '10.0.0.1',
		BW: {
			base_url: '../../images/',
			cookie: 'HOWTO-BA'
		},
		RT: {
			cookie: 'HOWTO-RT'
		}
	});
</script>
</body>
</html>
